# coding=utf-8
from flask import jsonify, url_for, request, make_response, Response
from flask_sqlalchemy import Pagination
from openpyxl.writer.excel import save_virtual_workbook

from config import HOST

PAGE_ID_FIELD = 'page_id'
PAGE_SIZE_FIELD = 'page_size'
DEFAULT_PAGE_SIZE = 20
MAX_PAGE_SIZE = 50

"""
{
    'code': 100010,           # error code
    'detail': detail,           # show for user
    'fields': fields,           # show for dev, list
    'success': true             # suc or fail
    'data': data,               # data if success else null, be list or dict
}
"""


def success_response(data: (list, dict) = None, page: dict = None) -> Response:
    result = {
        'code': 200,  # error code
        'detail': None,  # show for user
        'fields': None,  # show for dev, list
        'success': True,  # suc or fail
        'data': data,  # data if success else null, be list or dict
    }
    if page:
        result.update(page)
    return make_response(jsonify(result), 200)


def error_response(error=None, code=None, detail=None, fields: list = None):
    """
    给StandardErrorRecord， 或者同时给code和detail
    """
    from apps.a_common.error import ER
    if code is None and detail is None:
        error = ER.NOT_DEFINED if error is None else error
        code, detail = error.code, error.detail

    if not fields and error:
        fields = error.fields
    result = {
        'code': code,
        'detail': detail,
        'fields': fields,
        'success': False,
        'data': None,
    }
    return jsonify(result), 200


def excel_response(workbook, filename):
    content = save_virtual_workbook(workbook)
    response = make_response(content)
    response.headers.add("Content-Type", "application/vnd.ms-excel")
    response.headers.add('Content-Disposition', 'attachment', filename=filename.encode("utf-8").decode("latin1"))
    return response


def get_page_id_size():
    """
    获得页码和每页大小
    """
    page_id = int(request.args.get(PAGE_ID_FIELD, 1))
    page_size = int(request.args.get(PAGE_SIZE_FIELD, DEFAULT_PAGE_SIZE))
    page_size = MAX_PAGE_SIZE if page_size > MAX_PAGE_SIZE else page_size
    return page_id, page_size


def paginate_response(queryset, serializer):
    """
    返回200，并且加上分页信息
    """
    page_id, page_size = get_page_id_size()
    paginate: Pagination = queryset.paginate(page_id, per_page=page_size)
    data = [serializer(i) for i in paginate.items]
    page_info = make_paginate_info(paginate)
    return success_response(data, page_info)


def make_paginate_info(paginate: Pagination):
    """ 制作传统分页的分页信息 """
    endpoint = request.endpoint
    params = dict(request.args)
    params['page_id'] = paginate.next_num
    params['page_size'] = paginate.per_page

    next = None if paginate.next_num is None else HOST + url_for(endpoint, **params)
    params['page_id'] = paginate.prev_num
    previous = None if paginate.prev_num is None else HOST + url_for(endpoint, **params)
    return dict(next=next, previous=previous, count=paginate.total)


def empty_paginate_response(paginate: Pagination):
    endpoint = request.endpoint
    previous = None if paginate.prev_num is None else HOST + url_for(endpoint, page_id=paginate.prev_num,
                                                                     page_size=paginate.prev_num)
    return success_response([], dict(next=None, previous=previous, count=paginate.total))
